﻿
using System.Diagnostics;

using Mono.Cecil;
using Mono.Cecil.Cil;
using Mono.Cecil.Rocks;

public class LuaMethodDefinition : LuaMethodReference
{

    private readonly LuaTypeDefinition _owned;
    private readonly IReadOnlyList<LuaVariableDefinition> _variables;
    private readonly LuaArgDefinition _selfParameter;
    public bool IsStatic
        => Resolve<MethodDefinition>().IsStatic;
    public IReadOnlyList<LuaVariableDefinition> Locals
        => _variables;
    public LuaArgDefinition SelfArg => _selfParameter;

    private MethodBody _body;
    private BlockAnalysis _analysor;
    public LuaMethodDefinition(LuaModuleDefinition module, LuaTypeDefinition owned, MethodDefinition self)
    : base(module, self)
    {
        Debug.Assert(self.Body != null, "MethodBody Is Null!");
        _owned = owned;
        _variables = new List<LuaVariableDefinition>(from local in self.Body.Variables select new LuaVariableDefinition(module, this, local));
        if (self.HasThis)
            _selfParameter = new LuaArgDefinition(module, this, self.Body.ThisParameter);
        self.Body.Optimize();
        self.Body.OptimizeMacros();
        self.Body.SimplifyMacros();
        for (var i = 0; i < self.Body.Instructions.Count; i++)
            self.Body.Instructions[i].Offset = i;
        owned.Context.CurMethod = this;
        _body = self.Body;
        _analysor = new BlockAnalysis(owned.Context);
    }
    public LuaTypeDefinition Owned
        => _owned;

    internal void WriteTo(ICodeWriter writer)
    {
        writer.PushColor(ConsoleColor.DarkGray);
        writer.Comment($"method:{Self}");
        writer.PopColor();

        if (HasSelf)
            writer.CodeLine($"function this:{Name}({Join(',', Args.Select(x => x.Name))})");
        else
            writer.CodeLine($"function this.{Name}({Join(',', Args.Select(x => x.Name))})");
        writer.Indent++;
        _analysor.Analysis(_body.Instructions).WriteTo(writer);
        writer.Indent--;
        writer.Line();
        writer.CodeLine("end");
    }


}

